package com.bootdo.system.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.alibaba.fastjson.JSONObject;
import com.bootdo.common.dao.DictDao;
import com.bootdo.common.utils.ConvertUtil;
import com.bootdo.common.utils.FileUtil;
import com.bootdo.common.utils.HttpClientUtil;
import com.bootdo.common.utils.StringUtils;
import com.bootdo.system.dao.ListDao;
import com.bootdo.system.dao.ProductConfigDao;
import com.bootdo.system.dao.WithOrderPrintDao;
import com.bootdo.system.domain.ListDO;
import com.bootdo.system.domain.ProductConfigDO;
import com.bootdo.system.domain.WithOrderPrintDO;
import com.bootdo.system.service.ProductConfigService;
import com.bootdo.system.vo.ListWithOrderQueryVo;
import com.bootdo.system.vo.ListWithOrderVo;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


@Service
public class ProductConfigServiceImpl implements ProductConfigService {

    private static final Logger logger = LoggerFactory.getLogger(ProductConfigServiceImpl.class);
    @Autowired
    private ProductConfigDao productConfigDao;

    @Autowired
    private DictDao dictDao;

    @Autowired
    private ListDao listDao;

    @Autowired
    private WithOrderPrintDao withOrderPrintDao;

    @Override
    public ProductConfigDO get(Integer id) {
        return productConfigDao.get(id);
    }

    @Override
    public List<ProductConfigDO> list(Map<String, Object> map) {
        return productConfigDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return productConfigDao.count(map);
    }

    @Override
    public int save(ProductConfigDO config) {
        return productConfigDao.save(config);
    }

    @Override
    public int update(ProductConfigDO config) {
        return productConfigDao.update(config);
    }

    @Override
    public int remove(Integer id) {
        return productConfigDao.remove(id);
    }

    @Override
    public int batchRemove(Integer[] ids) {
        return productConfigDao.batchRemove(ids);
    }

    @Override
    public void importInfo(MultipartFile file) throws Exception {
        try {
            // 导入模板参数
            ImportParams importParams = new ImportParams();
            // easypoi 导入数据
            ExcelImportResult<ProductConfigDO> result =
                    ExcelImportUtil.importExcelMore(file.getInputStream(), ProductConfigDO.class, importParams);
            // 获取产品参数数据
            List<ProductConfigDO> list = result.getList();
            if (CollectionUtils.isNotEmpty(list)) {

                for (ProductConfigDO productConfigDO : list) {
                    if (StringUtils.isBlank(productConfigDO.getProductName())) {
                        continue;
                    }
                    //查询是否已经导入过
                    Integer existId = productConfigDao.getInfoByProNameAndGuige(productConfigDO);
                    if (null != existId) {
                        productConfigDO.setId(existId);
                        productConfigDao.update(productConfigDO);
                    } else {
                        productConfigDO.setIsDelete(0);
                        productConfigDao.save(productConfigDO);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("导入模板有误", e);
        }
    }

    @Override
    public List<ListWithOrderVo> getListWithOrder(Map<String, Object> map) {
        String type = (String) map.get("type");
        List<String> productPositionNumbers = dictDao.getValuesByType(type);
        String[] productPositionNumberAr = productPositionNumbers.toArray(new String[productPositionNumbers.size()]);
        map.put("productPositionNumbers", productPositionNumberAr);

        List<ListWithOrderVo> listWithOrderVos = productConfigDao.getListWithOrder(map);
        return buildList(listWithOrderVos);
    }

    private List<ListWithOrderVo> buildList(List<ListWithOrderVo> listWithOrderVos) {
        for (ListWithOrderVo listWithOrderVo : listWithOrderVos) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            listWithOrderVo.setFreightTime(format.format(listWithOrderVo.getFreightDate()));

            //计算金额
            String priceTax = listWithOrderVo.getPriceTax();
            String productAmount = listWithOrderVo.getProductAmount();
            if (StringUtils.isNotBlank(priceTax) && StringUtils.isNotBlank(productAmount)) {
                priceTax = new BigDecimal(priceTax).setScale(3, BigDecimal.ROUND_DOWN).toString();
                listWithOrderVo.setPriceTax(priceTax);
                listWithOrderVo.setAmountOrder(new BigDecimal(priceTax).multiply(new BigDecimal(productAmount)).setScale(3, BigDecimal.ROUND_DOWN));
            }

            //计算生产日期
            String validDate = listWithOrderVo.getValidDate();
            String expiryDate = listWithOrderVo.getExpiryDate();
            if (StringUtils.isNotBlank(expiryDate)) {
                String time = "";
                String productionDate = "";
                if (validDate.contains(".") && validDate.split(".").length == 2) {
                    time = validDate.split(".")[0] + "-" + validDate.split(".")[1];
                    productionDate = getProductionDate(1, time, Integer.valueOf(expiryDate));
                } else if (validDate.length() == 8) {
                    time = validDate.substring(0, 4) + "-" + validDate.substring(4, 6) + "-" + validDate.substring(6, 8);
                    productionDate = getProductionDate(0, time, Integer.valueOf(expiryDate));
                }
                listWithOrderVo.setProductionDate(productionDate);
            }
        }
        return listWithOrderVos;
    }

    @Override
    public int countListWithOrder(Map<String, Object> map) {
        String type = (String) map.get("type");
        List<String> productPositionNumbers = dictDao.getValuesByType(type);
        String[] productPositionNumberArr = productPositionNumbers.toArray(new String[productPositionNumbers.size()]);
        map.put("productPositionNumbers", productPositionNumberArr);
        return productConfigDao.countListWithOrder(map);
    }

    private String getProductionDate(int type, String time, Integer expiryDate) {
        Calendar cal = Calendar.getInstance();
        DateFormat simpleDateFormat = null;
        if (type == 0) {
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        } else {
            simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        }
        try {
            Date date = simpleDateFormat.parse(time);
            cal.setTime(date);
            cal.add(Calendar.MONTH, 0 - expiryDate);
            if (type == 0) {
                cal.add(Calendar.DATE, 1);
            }
            Date productionDate = cal.getTime();
            return simpleDateFormat.format(productionDate).replace("-", "");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public List<JSONObject> batchPrint(ListWithOrderQueryVo listWithOrderQueryVo) {
        //需要打印的传递单号
        String expressNos = listWithOrderQueryVo.getExpressNos();
        String[] expressNoArr = expressNos.split(",");
        List<String> expressNoList = new ArrayList<>();
        for (String expressNo : expressNoArr) {
            expressNo = expressNo.replace("\"", "");
            expressNo = expressNo.replace("[", "");
            expressNo = expressNo.replace("]", "");
            if (!expressNoList.contains(expressNo)) {
                expressNoList.add(expressNo);
            }
        }

        //发货日期
        String freightTime = listWithOrderQueryVo.getFreightTime();
        //根据传递单号和发货日期查询待打印的数据
        Map<String, List<ListWithOrderVo>> printMap = new LinkedHashMap<>();
        for (String expressNo : expressNoList) {
            Map<String, Object> map = new HashMap<>();
            map.put("freightDate", freightTime);
            map.put("expressNo", expressNo);
            String type = listWithOrderQueryVo.getType();
            List<String> productPositionNumbers = dictDao.getValuesByType(type);
            String[] productPositionNumberArr = productPositionNumbers.toArray(new String[productPositionNumbers.size()]);
            map.put("productPositionNumbers", productPositionNumberArr);

            List<ListWithOrderVo> deliverList = productConfigDao.getListWithOrder(map);
            deliverList = buildList(deliverList);
            printMap.put(expressNo, deliverList);

            //更新打印次数
            for (ListWithOrderVo listWithOrderVo : deliverList) {
                ListDO list = new ListDO();
                list.setId(listWithOrderVo.getDeliveryId());
                list.setWithOrderPrintNum(listWithOrderVo.getListWithOrderPrintNum() + 1);
                listDao.update(list);
            }
        }

        //调用打印服务
        List<JSONObject> resultList = printServer(listWithOrderQueryVo, printMap);


        //插入打印记录
        for (String expressNo : expressNoList) {
            WithOrderPrintDO withOrderPrintDO = new WithOrderPrintDO();
            withOrderPrintDO.setFreightDate(freightTime);
            withOrderPrintDO.setExpressNo(expressNo);
            withOrderPrintDO.setOperator(listWithOrderQueryVo.getOperator());
            withOrderPrintDO.setVendor(listWithOrderQueryVo.getSupplier());

            if ("医疗器械".equals(listWithOrderQueryVo.getType())) {
                withOrderPrintDO.setYlqxNo(listWithOrderQueryVo.getWithOrderNo());
                withOrderPrintDO.setStoreTransCondition(listWithOrderQueryVo.getTransCondition());
            }
            withOrderPrintDao.save(withOrderPrintDO);
        }

        return resultList;
    }

    private List<JSONObject> printServer(ListWithOrderQueryVo listWithOrderQueryVo, Map<String, List<ListWithOrderVo>> printMap) {
        String type = listWithOrderQueryVo.getType();
        String freightTime = listWithOrderQueryVo.getFreightTime();

        String footer = "<div style='display:flex; padding:0 30px; font-size:14px;justify-content: space-between; " +
                "margin-top:2px'><div>收货人：" +
                "</div><div>经办人：" +
                listWithOrderQueryVo.getOperator() +
                "</div><div><div>供货单位：" +
                listWithOrderQueryVo.getSupplier() +
                "</div><div style='text-align: center;'>出库专用章（盖章）：</div></div></div>";

        List<JSONObject> rowFontSizeList = new ArrayList<>();

        JSONObject expressNoAndTime = new JSONObject();
        expressNoAndTime.put("rowId", 0);
        expressNoAndTime.put("fontSize", 14);
        rowFontSizeList.add(expressNoAndTime);

        JSONObject company = new JSONObject();
        company.put("rowId", 1);
        company.put("fontSize", 14);
        rowFontSizeList.add(company);

        JSONObject receiveAddress = new JSONObject();
        receiveAddress.put("rowId", 2);
        receiveAddress.put("fontSize", 14);
        rowFontSizeList.add(receiveAddress);

        JSONObject[] rowFontSizes = rowFontSizeList.toArray(new JSONObject[rowFontSizeList.size()]);

        List<JSONObject> resultList = new ArrayList<>();
        for (Map.Entry<String, List<ListWithOrderVo>> entry : printMap.entrySet()) {
            String expressNo = entry.getKey();
            String deliverTime = freightTime.substring(0, 4) + "年" + freightTime.substring(5, 7) + "月" + freightTime.substring(8) + "日";
            List<ListWithOrderVo> deliverList = entry.getValue();
            if ("保健食品".equals(type)) {
                resultList.addAll(baoJianShiPin(expressNo, deliverTime, footer, rowFontSizes, deliverList));
            }
            if ("消杀用品".equals(type)) {
                resultList.addAll(xiaoShaYongPin(expressNo, deliverTime, footer, rowFontSizes, deliverList));
            }
            if ("医疗器械".equals(type)) {
                resultList.addAll(yiLiaoQiXie(expressNo, deliverTime, footer, rowFontSizes, listWithOrderQueryVo, deliverList));
            }
        }
        return resultList;
    }

    private List<JSONObject> baoJianShiPin(String expressNo, String deliverTime, String footer, JSONObject[] rowFontSizes, List<ListWithOrderVo> deliverList) {
        List<JSONObject> resultList = new ArrayList<>();
        //将list按照6等分，分成多页数据
        List<List<ListWithOrderVo>> parts = Lists.partition(deliverList, 6);
        for (List<ListWithOrderVo> list : parts) {
            JSONObject obj = new JSONObject();
            obj.put("fileName", "bjsp");
            obj.put("pageSize", 13);
            obj.put("headerRows", 4);
            obj.put("pageDesc", "no");
            obj.put("footer", footer);
            obj.put("rowFontSizes", rowFontSizes);

            List<String> valueList = new ArrayList<>();
            valueList.add("单据编号：;textAlign=l/" + expressNo + "/cp=7; ; ; ; ; ; ;发货日期;textAlign=l/" + deliverTime + "/cp=2; ");
            valueList.add("收货单位：;textAlign=l/" + deliverList.get(0).getCompany() + "/cp=10; ; ; ; ; ; ; ; ;");
            valueList.add("收货地址：;textAlign=l/" + deliverList.get(0).getReceiveAddress() + "/cp=10; ; ; ; ; ; ; ; ;");
            valueList.add("名称;规格;批号;批准文号;生产日期;有效期至;单位;数量;单价;金额;生产厂商");
            BigDecimal total = new BigDecimal(0);
            for (int i = 0; i < list.size(); i++) {
                total = total.add(list.get(i).getAmountOrder());
                valueList.add(list.get(i).getProductName() + ";" + list.get(i).getProductGuige() + ";" +
                        list.get(i).getBatchNumber() + ";" + list.get(i).getApprovalNumber() + ";" +
                        list.get(i).getProductionDate() + ";" + list.get(i).getValidDate() + ";" +
                        list.get(i).getUnit() + ";" + list.get(i).getProductAmount() + ";" +
                        list.get(i).getPriceTax() + ";" + list.get(i).getAmountOrder() + ";" +
                        list.get(i).getVendor());
            }
            //不足6条，补齐
            for (int j = list.size(); j % 6 != 0; j++) {
                valueList.add(" ; ; ; ; ; ; ; ; ; ; ;");
            }
            valueList.add("合计：;textAlign=r/大写:;" + ConvertUtil.convert(total) + "/cp=6; ; ; ; ; ;小写：;" + total + "/cp=2; ");

            String[] values = valueList.toArray(new String[valueList.size()]);
            obj.put("values", values);
            logger.info("保健食品obj：" + obj.toJSONString());
            resultList.add(obj);
        }
        return resultList;
    }

    private List<JSONObject> xiaoShaYongPin(String expressNo, String deliverTime, String footer, JSONObject[] rowFontSizes, List<ListWithOrderVo> deliverList) {
        List<JSONObject> resultList = new ArrayList<>();
        //将list按照6等分，分成多页数据
        List<List<ListWithOrderVo>> parts = Lists.partition(deliverList, 6);
        for (List<ListWithOrderVo> list : parts) {
            JSONObject obj = new JSONObject();
            obj.put("fileName", "xsyp");
            obj.put("pageSize", 13);
            obj.put("headerRows", 4);
            obj.put("pageDesc", "no");
            obj.put("footer", footer);
            obj.put("rowFontSizes", rowFontSizes);

            List<String> valueList = new ArrayList<>();
            valueList.add("单据编号：;textAlign=l/" + expressNo + "/cp=7; ; ; ; ; ; ;发货日期;textAlign=l/" + deliverTime + "/cp=2; ");
            valueList.add("收货单位：;textAlign=l/" + deliverList.get(0).getCompany() + "/cp=10; ; ; ; ; ; ; ; ;");
            valueList.add("收货地址：;textAlign=l/" + deliverList.get(0).getReceiveAddress() + "/cp=10; ; ; ; ; ; ; ; ;");
            valueList.add("产品名称;规格;许可证号/备案号;批号;单位;数量;单价;金额;生产日期;有效期至;生产厂商");
            BigDecimal total = new BigDecimal(0);
            for (int i = 0; i < list.size(); i++) {
                total = total.add(list.get(i).getAmountOrder());
                valueList.add(list.get(i).getProductName() + ";" + list.get(i).getProductGuige() + ";" +
                        list.get(i).getLicenseKey() + ";" + list.get(i).getBatchNumber() + ";" +
                        list.get(i).getUnit() + ";" + list.get(i).getProductAmount() + ";" +
                        list.get(i).getPriceTax() + ";" + list.get(i).getAmountOrder() + ";" +
                        list.get(i).getProductionDate() + ";" + list.get(i).getValidDate() + ";" +
                        list.get(i).getVendor());
            }
            //不足6条，补齐
            for (int j = list.size(); j % 6 != 0; j++) {
                valueList.add(" ; ; ; ; ; ; ; ; ; ; ;");
            }
            valueList.add("合计：;textAlign=r/大写:;" + ConvertUtil.convert(total) + "/cp=6; ; ; ; ; ;小写：;" + total + "/cp=2; ");

            String[] values = valueList.toArray(new String[valueList.size()]);
            obj.put("values", values);
            logger.info("消杀用品obj：" + obj.toJSONString());
            resultList.add(obj);
        }
        return resultList;
    }

    private List<JSONObject> yiLiaoQiXie(String expressNo, String deliverTime, String footer, JSONObject[] rowFontSizes,
                                         ListWithOrderQueryVo listWithOrderQueryVo, List<ListWithOrderVo> deliverList) {
        List<JSONObject> resultList = new ArrayList<>();
        //将list按照6等分，分成多页数据
        List<List<ListWithOrderVo>> parts = Lists.partition(deliverList, 6);
        for (List<ListWithOrderVo> list : parts) {
            JSONObject obj = new JSONObject();
            obj.put("fileName", "ylqx");
            obj.put("pageSize", 13);
            obj.put("headerRows", 3);
            obj.put("pageDesc", "no");
            //医疗器械随行单的编号
            obj.put("reportCode", "编号：" + listWithOrderQueryVo.getWithOrderNo());
            obj.put("footer", footer);
            obj.put("rowFontSizes", rowFontSizes);

            List<String> valueList = new ArrayList<>();
            valueList.add("单据编号：;textAlign=l/" + expressNo + "/cp=7; ; ; ; ; ; ;发货日期;" + deliverTime + "/cp=2; ");
            valueList.add("收货单位：;textAlign=l/" + deliverList.get(0).getCompany() + "/cp=10; ; ; ; ; ; ; ; ;");
            valueList.add("收货地址：;textAlign=l/" + deliverList.get(0).getReceiveAddress() + "/cp=10; ; ; ; ; ; ; ; ;");
            valueList.add("产品名称;规格/型号;注册证号/备案凭证编号;批号/序列号;数量;单价;金额;储运条件;生产厂商;许可证号/备案凭证号;有效期/失效期");
            BigDecimal total = new BigDecimal(0);
            for (int i = 0; i < list.size(); i++) {
                //处理 注册证号/备案凭证编号 和 许可证号/备案凭证号 和生产厂商 为空时的打印展示问题
                if (StringUtils.isBlank(list.get(i).getRegistrationCertificateNo())) {
                    list.get(i).setRegistrationCertificateNo("");
                }
                if (StringUtils.isBlank(list.get(i).getLicenseKey())) {
                    list.get(i).setLicenseKey("");
                }

                if (StringUtils.isBlank(list.get(i).getVendor())) {
                    list.get(i).setVendor("");
                }

                total = total.add(list.get(i).getAmountOrder());
                valueList.add(list.get(i).getProductName() + ";" + list.get(i).getProductGuige() + ";" +
                        list.get(i).getRegistrationCertificateNo() + ";" + list.get(i).getBatchNumber() + ";" +
                        list.get(i).getProductAmount() + ";" + list.get(i).getPriceTax() + ";" +
                        list.get(i).getAmountOrder() + ";" + listWithOrderQueryVo.getTransCondition() + ";" +
                        list.get(i).getVendor() + ";" + list.get(i).getLicenseKey() + ";" +
                        list.get(i).getValidDate());
            }
            //不足6条，需要补齐
            for (int j = list.size(); j % 6 != 0; j++) {
                valueList.add(" ; ; ; ; ; ; ; ; ; ; ;");
            }
            valueList.add("合计：;textAlign=r/大写:;" + ConvertUtil.convert(total) + "/cp=6; ; ; ; ; ;小写：;" + total + "/cp=2; ");

            String[] values = valueList.toArray(new String[valueList.size()]);
            obj.put("values", values);
            logger.info("医疗器械obj：" + obj.toJSONString());
            resultList.add(obj);
        }
        return resultList;
    }


}
